package com.yeskery.nut.application.sun;

import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsParameters;
import com.sun.net.httpserver.HttpsServer;
import com.yeskery.nut.application.NutServerConfigure;
import com.yeskery.nut.application.SecureServerContext;
import com.yeskery.nut.core.NutException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.logging.Logger;

/**
 * 基于JDK的HttpServer实现HTTPS服务
 * @author sprout
 * 2022-05-19 13:09
 */
public class SunSecureNutServer extends SunNutServer {

    /** 日志对象 */
    private static final Logger logger = Logger.getLogger(SunSecureNutServer.class.getName());

    /** Http 服务 */
    private HttpsServer httpsServer;

    /** SecureServerContext对象 */
    private final SecureServerContext secureServerContext;

    /**
     * 构建HTTPS服务
     * @param secureServerContext SecureServerContext对象
     */
    public SunSecureNutServer(SecureServerContext secureServerContext) {
        if (secureServerContext == null) {
            throw new NutException("SecureServerContext Interface Must Not Be Null.");
        }
        this.secureServerContext = secureServerContext;
    }

    @Override
    public void startServer(NutServerConfigure nutServerConfigure) throws Exception {
        httpsServer = HttpsServer.create(new InetSocketAddress(nutServerConfigure.getPort()), MAX_WAIT_SIZE);
        httpsServer.setHttpsConfigurator(new HttpsConfigurator(secureServerContext.getSslContext()) {
            @Override
            public void configure (HttpsParameters params)
            {
                try
                {
                    SSLContext sslContext = SSLContext.getDefault();
                    SSLEngine engine = sslContext.createSSLEngine();
                    params.setNeedClientAuth (false);
                    params.setCipherSuites(engine.getEnabledCipherSuites());
                    params.setProtocols(engine.getEnabledProtocols());
                    params.setSSLParameters(sslContext.getDefaultSSLParameters());
                } catch (Exception e) {
                    throw new NutException("Sun Nut Server Start Fail.", e);
                }
            }
        });

        logger.info(getServerStartedTip(nutServerConfigure.getPort(), "SUN", true));
        httpsServer.setExecutor(nutServerConfigure.getNutApplication().getDefaultThreadPool().getThreadPool());
        httpsServer.createContext("/", new ControllerHttpHandler(nutServerConfigure.getNutApplication(),
                nutServerConfigure.getServerContext(), nutServerConfigure.getDispatcher(),
                nutServerConfigure.getSessionManager(), nutServerConfigure.getServerRequestConfiguration(), this));
        httpsServer.start();
    }

    @Override
    public void close() throws IOException {
        if (httpsServer != null) {
            httpsServer.stop(MAX_WAIT_TIME);
        }
    }
}
